package com.riekoff.particlecubeworld.editor.zonierung;

import java.io.File;

import cc.creativecomputing.control.CCControl;
import cc.creativecomputing.graphics.CCColor;
import cc.creativecomputing.graphics.texture.CCTexture.CCTextureFilter;
import cc.creativecomputing.graphics.texture.CCTexture.CCTextureTarget;
import cc.creativecomputing.graphics.texture.CCTexture.CCTextureWrap;
import cc.creativecomputing.graphics.texture.CCTexture2D;
import cc.creativecomputing.graphics.texture.CCTextureData;
import cc.creativecomputing.graphics.texture.CCTextureIO;
import cc.creativecomputing.graphics.texture.video.CCSequenceTexture;
import cc.creativecomputing.io.CCIOUtil;

import com.riekoff.particlecubeworld.editor.AFigurenEditor;
import com.riekoff.particlecubeworld.editor.ATilePattern;

public class ADirectEditZonierung implements AZonierung{
	
	public static enum AZonierungMode{
		DIRECT, SCREENGRAB, MOVIE
	}

	@CCControl(name = "zone 0", min = 0, max = 4)
	public int _cZone0 = 0;
	@CCControl(name = "zone 1", min = 0, max = 4)
	public int _cZone1 = 0;
	@CCControl(name = "zone 2", min = 0, max = 4)
	public int _cZone2 = 0;
	@CCControl(name = "zone 3", min = 0, max = 4)
	public int _cZone3 = 0;
	@CCControl(name = "zone 4", min = 0, max = 4)
	public int _cZone4 = 0;
	@CCControl(name = "zone 5", min = 0, max = 4)
	public int _cZone5 = 0;
	@CCControl(name = "zone 6", min = 0, max = 4)
	public int _cZone6 = 0;
	@CCControl(name = "zone 7", min = 0, max = 4)
	public int _cZone7 = 0;
	@CCControl(name = "zone 8", min = 0, max = 4)
	public int _cZone8 = 0;
	@CCControl(name = "zone 9", min = 0, max = 4)
	public int _cZone9 = 0;

	@CCControl(name = "zone 10", min = 0, max = 4)
	public int _cZone10 = 0;
	@CCControl(name = "zone 11", min = 0, max = 4)
	public int _cZone11 = 0;
	@CCControl(name = "zone 12", min = 0, max = 4)
	public int _cZone12 = 0;
	@CCControl(name = "zone 13", min = 0, max = 4)
	public int _cZone13 = 0;
	@CCControl(name = "zone 14", min = 0, max = 4)
	public int _cZone14 = 0;
	@CCControl(name = "zone 15", min = 0, max = 4)
	public int _cZone15 = 0;
	@CCControl(name = "zone 16", min = 0, max = 4)
	public int _cZone16 = 0;
	@CCControl(name = "zone 17", min = 0, max = 4)
	public int _cZone17 = 0;
	@CCControl(name = "zone 18", min = 0, max = 4)
	public int _cZone18 = 0;
	@CCControl(name = "zone 19", min = 0, max = 4)
	public int _cZone19 = 0;

	@CCControl(name = "zone 20", min = 0, max = 4)
	public int _cZone20 = 0;
	@CCControl(name = "zone 21", min = 0, max = 4)
	public int _cZone21 = 0;
	@CCControl(name = "zone 22", min = 0, max = 4)
	public int _cZone22 = 0;
	@CCControl(name = "zone 23", min = 0, max = 4)
	public int _cZone23 = 0;
	@CCControl(name = "zone 24", min = 0, max = 4)
	public int _cZone24 = 0;
	
	private CCTexture2D _myTexture;
	private ATilePattern _myPattern;
	private AZonierungData _myData;
	
	@CCControl(name = "mode")
	private AZonierungMode _cMode = AZonierungMode.DIRECT;
	
	@CCControl(name = "clamp to pattern")
	private boolean _cClampToPatternWidth = true;
	
	@CCControl(name = "pattern scale", min = 0, max = 10)
	private float _cPatternScale = 1f;
	
	@CCControl(name = "movie index", min = 0, max = 20)
	private int _cMovieIndex = 0;
	
	@CCControl(name = "movie framerate", min = 1, max = 30)
	private int _cMovieRate = 30;
	
	public ADirectEditZonierung(AZonierungData theZonierungsData){
		_myData = theZonierungsData;
		_myTexture = new CCTexture2D(100,100, CCTextureTarget.TEXTURE_2D);
		_myTexture.textureFilter(CCTextureFilter.NEAREST);
	}
	
	public float patternScale(){
		return _cPatternScale;
	}
	
	public boolean clampToPattern(){
		return _cClampToPatternWidth;
	}
	
	public void pattern(ATilePattern thePattern){
		_myPattern = thePattern;
	}
	
	private CCTextureData createData(boolean invert){
		int[] myZones = new int[]{
			_cZone0,  _cZone1,  _cZone2,  _cZone3,  _cZone4,  _cZone5,  _cZone6,  _cZone7,  _cZone8,  _cZone9,
			_cZone10, _cZone11, _cZone12, _cZone13, _cZone14, _cZone15, _cZone16, _cZone17, _cZone18, _cZone19,
			_cZone20, _cZone21, _cZone22, _cZone23, _cZone24
		};
		CCTextureData myData = new CCTextureData(_myPattern.width, _myPattern.height);
		for(int x = 0; x < _myPattern.width;x++){
			for(int y = 0; y < _myPattern.height;y++){
				int myIndex = _myPattern.tileindices[x][y];
				if(myIndex >= myZones.length)continue;
				int myZoneValue = myZones[myIndex];
				myData.setPixel(x, invert ? _myPattern.height - 1 - y : y, new CCColor(myZoneValue * 0.2f + 0.1f));
			}
		}
		return myData;
	}
	
	private CCTexture2D directMode(){
		if(_myPattern == null)return _myTexture;
		
		_myTexture.data(createData(false));
		_myTexture.textureFilter(CCTextureFilter.NEAREST);
		_myTexture.wrap(CCTextureWrap.REPEAT);
		return _myTexture;
	}
	
	private CCSequenceTexture _myMovie = null;
	
	public void update(final float theDeltaTime){
		switch(_cMode){
		case MOVIE:
			_myMovie = _myData.movie(_cMovieIndex);
			if(_myMovie != null){
				_myMovie.update(theDeltaTime);
				_myMovie.frameRate(_cMovieRate);
			}
			break;
		}
	}
	
	@Override
	public CCTexture2D zoneTexture() {
		switch(_cMode){
		case DIRECT:
			return directMode();
		case SCREENGRAB:
			return _myData.grabTexture();
		case MOVIE:
			if(_myMovie != null)return _myMovie;
		}
		return directMode();
	}
	
	public String filePath(){
		switch(_cMode){
		case DIRECT:
			if(_myOutPath == null)saveTexture();
			int myStart = _myOutPath.indexOf("data" + File.separator + "zonierungen"); 
			if(myStart < 0)return null;
			int myEnd = _myOutPath.lastIndexOf(File.separator);
			
			return _myOutPath.substring(myStart, myEnd);
		case SCREENGRAB:
			return null;
		case MOVIE:
			if(_myMovie != null)return _myData.moviePath(_cMovieIndex);
		}
		return null;
	}
	
	private String _myOutPath = null;
	
	@CCControl(name = "save")
	public void saveTexture(){
		if(!AFigurenEditor._cSaveActive){
			return;
		}
		CCIOUtil.createPath(CCIOUtil.appPath("data/zonierungen/zone.bla"));
		_myOutPath =  CCIOUtil.selectOutput("save zonierung", CCIOUtil.appPath("data/zonierungen"));
		
		if(_myOutPath == null)return;
		_myOutPath = _myOutPath + "/zones.png";
		CCIOUtil.createPath(_myOutPath);
		CCTextureIO.write(createData(true),_myOutPath);
	}
}
